package com.bdth.controller;

import com.bdth.model.*;
import com.bdth.service.IAlarmConfigService;
import com.bdth.service.IDepartmentService;
import com.bdth.service.IDeviceService;
import com.bdth.service.IRealDataService;
import com.bdth.utils.HtmlUtil;
import com.bdth.utils.SessionUtils;
import com.bdth.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author: 徐斌
 * @Date: 2018-03-20 9:37
 */
@Controller
@RequestMapping("/deviceTree")
public class DeviceTreeController extends BaseController {

	protected static final Logger logger = LoggerFactory.getLogger(DeviceTreeController.class);

	/**
	 * 存放授权单位Id map的可以
	 */
	protected static String SESSION_KEY_DEP = "session_key_department";

	Map<Integer, Department> depMap = new HashMap<Integer, Department>();

	private List<ZTreeNode> zTreeNodeList = new ArrayList<ZTreeNode>();

	//存放更新数据集合
	private List<ZTreeNode> zTreeNodeUpdateList = new ArrayList<ZTreeNode>();

	int totalNum = 0;
	int onlineNum = 0;

	//行驶数量
	int travelNum = 0;
	//停车数量
	int parkingNum = 0;

	@Autowired
	private IDepartmentService departmentService;

	@Autowired
	private IDeviceService deviceService;

	@Autowired
	private IRealDataService realDataService;

	@Autowired
	private IAlarmConfigService alarmConfigService;

	/**
	 * 前台刷新设备数的标志，表示是更新节点的状态，而不是创建
	 */
	private Boolean updateNode = false;

	// 生成设备树菜单
	@RequestMapping("/getDeviceTree")
	public void getDeviceTree(HttpServletRequest request, HttpServletResponse response, Boolean updateNode) {
		this.updateNode = updateNode;
		zTreeNodeList.clear();
		zTreeNodeUpdateList.clear();
		Map<String, Object> resultMap = new HashMap<String, Object>();
		this.totalNum = 0;
		this.onlineNum = 0;

		//行驶数量
		this.travelNum = 0;
		//停车数量
		this.parkingNum = 0;

		try {
			Map<String, Object> mapDep = new HashMap<String, Object>();
			User user = SessionUtils.getUser(request);

			List<Integer> depIds = getDepIds(user.getDepId());
			mapDep.put("depIds", depIds);

			// 用户分配的车队
			List<Department> depSet = departmentService.queryByMapList(mapDep);
			List<Department> depList = new ArrayList<Department>();

			Map<Integer, Integer> nodeMap = new HashMap<Integer, Integer>();
			if (depSet != null) {
				for (Department dep : depSet) {
					depList.add(dep);
				}
			}

			List<Department> allDepList = departmentService.queryByMapList(new HashMap());

			for (Object obj : allDepList) {
				Department dep = (Department) obj;
				depMap.put(dep.getId(), dep);
			}
			createDeviceTreeNode(request);// 创建设备树节点
			// 生成部门树
		/*	Collections.sort(depList, new Comparator<Department>() {
				public int compare(Department o1, Department o2) {
					if (o1.getDepName() == null)
						return -1;

					return o1.getDepName().compareTo(o2.getDepName());
				}

			});*/
			for (Department d : depList) {
				Department dep = depMap.get(d.getId());
				if (dep == null)
					continue;
				setTreeData(dep, request);
			}

		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

		resultMap.put("TreeDataIndex", zTreeNodeList);
		resultMap.put("UpdateTreeDataIndex", zTreeNodeUpdateList);
		// 统计上线车辆数和上线率,显示在前台
		Map onlineInfo = new HashMap();
		onlineInfo.put("onlineNum", onlineNum);
		onlineInfo.put("totalNum", totalNum);
		onlineInfo.put("travelNum", travelNum);
		onlineInfo.put("parkingNum", parkingNum);
		int offlineNum = totalNum - onlineNum;
		onlineInfo.put("offlineNum", offlineNum);
		double onlineRate = 0;
		if (totalNum > 0 && onlineNum > 0)
			onlineRate = 100.00 * onlineNum / totalNum;
		if (onlineRate > 0) {
			DecimalFormat df = new DecimalFormat("######0.00");
			String rate = df.format(onlineRate);
			onlineInfo.put("onlineRate", rate);
		} else
			onlineInfo.put("onlineRate", "0");

		resultMap.put("onlineInfo", onlineInfo);
		HtmlUtil.writerJson(response, resultMap);
	}


	/**
	 * 创建设备树节点
	 */
	private void createDeviceTreeNode(HttpServletRequest request) throws Exception {
		String path = request.getContextPath();
		Date start = new Date();
		Map<String, Object> params = new HashMap<String, Object>();
		User user = SessionUtils.getUser(request);
		List result = null;
		//params.put("userId", user.getId());
		List<Integer> depIds = getDepIds(user.getDepId());
		params.put("depIds", depIds);
		result = deviceService.queryDeviceTree(params);
		if (result == null)
			result = new ArrayList();

		this.totalNum = result.size();
		Map<String, GPSRealData> realMap = new HashMap<String, GPSRealData>();
		List<String> simNos = new ArrayList<String>();
		for (Object o : result) {
			Map rowData = (Map) o;
			String simNo = "realData_" + rowData.get("SimNo");
			simNos.add(simNo);
		}

		List<GPSRealData> onlineRealDataList = realDataService.getRealDataList(simNos);
		if (onlineRealDataList != null) {
			try {
				for (GPSRealData rd : onlineRealDataList) {
					realMap.put(rd.getSimNo(), rd);
				}
			} catch (Exception e) {
				logger.error(e.getMessage());
			}
		}

		for (Object obj : result) {
			Map rowData = (Map) obj;
			String simNo = "" + rowData.get("SimNo");
			int vehicleId = (Integer) rowData.get("id");
			int depId = (Integer) rowData.get("DepId");
			String equipName = "" + rowData.get("equipName");
			double velocity = 0;
			String strVelocity = "";
			//String onlineStatus = "" + rowData.get("online");
			int online = 0;// "true".equals(onlineStatus);
			String alarm = "";
			if (realMap.size() > 0) {
				GPSRealData rd = realMap.get(simNo);
				if (rd != null) {
					online = rd.getOnline();
					strVelocity = "" + rd.getVelocity();
					velocity = Double.parseDouble(strVelocity);
					//alarm = getAlarmDescr("" + rd.getAlarmState());
				} else
					online = 0;
			}

			String icon = "offline"; // 离线图标
			if (online == 3) {
				this.onlineNum++;
				if (velocity > 1) {
					this.travelNum++;
					icon = "online"; // 运行图标
				} else {
					icon = "parking";// 停车图标
					this.parkingNum++;
				}

			}
			if (online == 4) {
				icon = "alarm"; // 报警图标
			}
			String tid = "v" + vehicleId;
			String parentNodeId = "dep" + depId;
			ZTreeNode mzTn = new ZTreeNode(tid, equipName, parentNodeId, path + "/images/ztree/" + icon + ".png", simNo);
			boolean isRefresh = needRefresh(mzTn, request);
			if (this.updateNode) {
				if (isRefresh) {
					zTreeNodeUpdateList.add(mzTn);
				}
			} else {
				zTreeNodeList.add(mzTn);
			}

			Department dep = depMap.get(depId);
			while (dep != null) {
				dep.setTotalNum(dep.getTotalNum() + 1);
				if (online == 3)
					dep.setOnlineNum(dep.getOnlineNum() + 1);
				dep = depMap.get(dep.getParentDepId());
			}

		}
		Date end = new Date();

		//log.error("实时数据刷新耗时:" + seconds + ",条数：" + result.size());
	}

	private void setTreeData(Department dep, HttpServletRequest request) {
		String path = request.getContextPath();
		try {
			String depNodeId = "dep" + dep.getId();
			int parentId = dep.getParentDepId();
			// parentId = parentId > 0 ? ("dep_"+parentId) : 1;
			String strParentNodeId = "dep" + parentId;
			ZTreeNode mzTn = new ZTreeNode(depNodeId, dep.getDepName(),
					strParentNodeId, path + "/images/ztree/dep.png", false, dep.getTotalNum(), dep.getOnlineNum());

			boolean isRefresh = needRefresh(mzTn, request);
			if (this.updateNode) {
				// 如果前后节点没有变化，就更新节点的状态
				if (isRefresh)
					zTreeNodeUpdateList.add(mzTn);
			} else {
				zTreeNodeList.add(mzTn);
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
	}


	private Map<String, ZTreeNode> getNodeMapFromSession(HttpServletRequest request) {
		String SESSION_FOR_TREE_NODE_MAP = "DeviceTreeNodeMap";
		Map<String, ZTreeNode> nodeMap = (Map<String, ZTreeNode>) request.getSession(true).getAttribute(SESSION_FOR_TREE_NODE_MAP);
		if (nodeMap == null) {
			nodeMap = new HashMap<String, ZTreeNode>();
			//nodeMap.put(tn.getNodeId(), tn);
			request.getSession(true).setAttribute(SESSION_FOR_TREE_NODE_MAP, nodeMap);
			//return true;
		}
		return nodeMap;
	}

	private void cacheNodeInSession(ZTreeNode tn, HttpServletRequest request) {
		Map<String, ZTreeNode> nodeMap = getNodeMapFromSession(request);
		//nodeMap[tn.getNodeId()] = tn;
		nodeMap.put(tn.getNodeId(), tn);
	}

	private boolean needRefresh(ZTreeNode tn, HttpServletRequest request) {
		Map<String, ZTreeNode> nodeMap = getNodeMapFromSession(request);
		if (nodeMap.containsKey(tn.getNodeId()) == false) {
			cacheNodeInSession(tn, request);
			return true;
		}

		ZTreeNode oldTn = (ZTreeNode) nodeMap.get(tn.getNodeId());

		if (oldTn.getIcon().equals(tn.getIcon())
				&& oldTn.getText().equals(tn.getText())) {
			// 节点没有变化不需要刷新
			nodeMap.put(tn.getNodeId(), tn);
			return false;
		}
		nodeMap.put(tn.getNodeId(), tn);
		return true;
	}

	/**
	 * 报警描述
	 *
	 * @param alarm
	 * @return
	 */
	protected String getAlarmDescr(String alarm) {
		StringBuilder sb = new StringBuilder();

		if (StringUtil.isEmptyWithNullStr(alarm) == false) {
			char[] ch = alarm.toCharArray();
			for (int m = 0; m < ch.length; m++) {
				int tag = Integer.parseInt("" + ch[m]);
				if (tag == 1) {
					int alarmId = 31 - m; // 倒序，转换为部标的报警序号
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("alarmType", "" + alarmId);
					List<AlarmConfig> bd = alarmConfigService.queryByAlarmType(map);
					if (bd != null && bd.size() > 0) {
						sb.append(bd.get(0).getName()).append(",");
					}
				}
			}
		}

		return sb.toString();
	}

}
